package com.iot.ammeter.service.impl.web.other;

import com.iot.ammeter.constant.Constant;
import com.iot.ammeter.exception.BusinessExceptions;
import com.iot.ammeter.service.other.UploadImageService;
import com.iot.ammeter.utils.SnowFlakeIdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @ClassName: UploadImageServiceImpl
 * @Author: Basil
 * @Date: 2021/10/9 下午2:38
 * @Version: 1.0
 * @Description: 图片上传服务实现类
 **/
@Service
@Slf4j
public class UploadImageServiceImpl implements UploadImageService {
    @Value("${image.image-path}")
    private String imagePath;
    @Value("${image.max-size}")
    private long maxSize;

    private final SimpleDateFormat simpleDateFormat;
    private final SnowFlakeIdWorker snowFlakeIdWorker;

    public UploadImageServiceImpl(SimpleDateFormat simpleDateFormat, SnowFlakeIdWorker snowFlakeIdWorker) {
        this.simpleDateFormat = simpleDateFormat;
        this.snowFlakeIdWorker = snowFlakeIdWorker;
    }

    /**
     * 上传图片
     *
     * @param img  图片
     * @param type 1为logo 2为头像
     * @return 返回图片上传后的路径
     */
    @Override
    public String uploadImage(MultipartFile img, String type) {
        /**
         * 判断是否有文件
         */
        if (img == null) {
            throw new BusinessExceptions("文件为空");
        }
        /**
         * 判断文件类型，.png,.jpeg ....
         */
        String contentType = img.getContentType();

        if (StringUtils.isEmpty(contentType)) {
            throw new BusinessExceptions("图片格式错误");
        }
        if (!Constant.Img.PNG.equals(contentType) && !Constant.Img.GIF.equals(contentType) && !Constant.Img.JPEG.equals(contentType)) {
            throw new BusinessExceptions("不支持该图片类型");
        }
        /**
         * 限制图片大小
         */
        long size = img.getSize();
        if (size > maxSize) {
            throw new BusinessExceptions("图片最大支持" + (maxSize / 1024) + "KB");
        }
        /**
         * 创建文件保存目录
         *      规则：配置文件目录/日期/类型/id.类型
         */
        type = type.trim();
        String currentDay = simpleDateFormat.format(new Date());
        String currentType = Constant.Img.LOGO.equals(type) ? "logo" : "avatar";
        String typePath = imagePath + File.separator + currentType;
        File typePathFile = new File(typePath);
        //判断类型文件夹是否存在,不存在则创建
        if (!typePathFile.exists()) {
            typePathFile.mkdirs();
        }
        String dayPath = imagePath + File.separator + currentType + File.separator + currentDay;
        File datPathFile = new File(dayPath);
        //判断日期文件夹是否存在,不存在则创建
        if (!datPathFile.exists()) {
            datPathFile.mkdirs();
        }
        String templatePath = File.separator + currentType +
                File.separator + currentDay + File.separator + snowFlakeIdWorker.nextId() + "." + contentType.split("/")[1];
        String targetPath = imagePath + templatePath;
        File targetFile = new File(targetPath);
        try {
            //获取当前主机(服务器)ip地址及端口号
            HttpServletRequest request = getRequest();
            String ip = InetAddress.getLocalHost().getHostAddress();
            img.transferTo(targetFile);
            return request.getScheme() + "://" + ip + ":" + request.getServerPort() + "/img" + templatePath;
        } catch (IOException e) {
            e.printStackTrace();
            return "图片上传失败";
        }
    }

    /**
     * 获取request
     *
     * @return request
     */
    public HttpServletRequest getRequest() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return attributes.getRequest();
    }
}
